package com.richie696.rabbit.order.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.richie696.rabbit.commons.ExecuteResult;
import com.richie696.rabbit.commons.SnowFlake;
import com.richie696.rabbit.order.domain.OrderInfo;
import com.richie696.rabbit.order.enums.OrderStatus;
import com.richie696.rabbit.order.mapper.OrderMapper;
import com.richie696.rabbit.order.service.OrderService;
import com.richie696.rabbit.product.domain.ProductInfo;
import com.richie696.rabbit.product.service.ProductService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.amqp.core.AmqpTemplate;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.MessagePropertiesBuilder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Objects;

import static com.richie696.rabbit.commons.RabbitKey.*;

@Service
public class OrderServiceImpl implements OrderService {

    private static final Logger LOGGER = LoggerFactory.getLogger(OrderServiceImpl.class);
    private final OrderMapper orderMapper;
    private final ProductService productService;
    private final AmqpTemplate amqpTemplate;

    @Autowired
    public OrderServiceImpl(OrderMapper orderMapper, ProductService productService, AmqpTemplate amqpTemplate) {
        this.orderMapper = orderMapper;
        this.productService = productService;
        this.amqpTemplate = amqpTemplate;
    }

    @Override
    public List<OrderInfo> findOrdersByUserId(Long userId) {
        return orderMapper.selectList(new QueryWrapper<OrderInfo>().eq("user_id", userId));
    }

    @Override
    public ExecuteResult<?> doBuy(Long userId, Long productId, Integer count) {
        ExecuteResult<ProductInfo> productExec = productService.findProductById(productId);
        if (!productExec.isSuccess()) {
            return productExec;
        }
        ProductInfo productInfo = productExec.getData();
        OrderInfo orderInfo = new OrderInfo()
                .setUserId(userId)
                .setOrderId("O-" + new SnowFlake(1, 1).nextId())
                .setStatus(OrderStatus.CREATE.getId())
                .setPrice(productInfo.getPrice() * count)
                .setName(productInfo.getName())
                .setCount(count)
                .setProductId(productId);
        int res = orderMapper.insert(orderInfo);
        if (res != 1) {
            return ExecuteResult.getErrorResult("下单失败。");
        }
        // 设置消息属性
        MessageProperties properties = MessagePropertiesBuilder.newInstance()
                .setContentType(MessageProperties.CONTENT_TYPE_TEXT_PLAIN)
                .setContentEncoding(StandardCharsets.UTF_8.name())
                .setHeader("userId", orderInfo.getUserId())
                .setExpiration(EXPIRATION.toString())
                .build();
        Message message = new Message(orderInfo.getOrderId().getBytes(StandardCharsets.UTF_8), properties);
        // 发送TTL消息
        amqpTemplate.convertAndSend(ORDER_EXCHANGE_TTL, ORDER_KEY_TTL, message);
        return ExecuteResult.getSuccess(orderInfo);
    }

    @Override
    public ExecuteResult<Long> doPayment(Long userId, String orderId) {
        Message message = amqpTemplate.receive(ORDER_QUEUE_TTL);
        if (Objects.isNull(message)) {
            return ExecuteResult.getErrorResult("当前订单已过期。");
        }
        OrderInfo orderInfo = orderMapper.selectOne(new QueryWrapper<OrderInfo>()
                .eq("user_id", userId).eq("order_id", orderId));
        if (Objects.isNull(orderInfo)) {
            LOGGER.error("订单不存在。(userId = {}, orderId = {})", userId, orderId);
            return ExecuteResult.getErrorResult("订单不存在。(orderId = {})", orderId);
        }
        orderInfo.setStatus(OrderStatus.FINISHED.getId());
        int res = orderMapper.updateById(orderInfo);
        if (res != 1) {
            throw new RuntimeException("付款失败");
        }
        return ExecuteResult.getSuccess();
    }

    @Override
    public void doExpiredRefresh(Long userId, String orderId) {
        OrderInfo orderInfo = orderMapper.selectOne(new QueryWrapper<OrderInfo>()
                .eq("user_id", userId).eq("order_id", orderId));
        if (Objects.isNull(orderInfo)) {
            LOGGER.error("订单不存在。(userId = {}, orderId = {})", userId, orderId);
            return;
        }
        orderInfo.setStatus(OrderStatus.CLOSED.getId());
        int res = orderMapper.updateById(orderInfo);
        if (res == 1) {
            LOGGER.info("订单关闭成功。(userId = {}, orderId = {})", userId, orderId);
        } else {
            LOGGER.error("订单关闭失败。(userId = {}, orderId = {})", userId, orderId);
        }
    }
}
